<template>
  <div class="infinite-scroll" ref="pullLoadRef">
    <div
      :class="className"
      :style="style"
      :infinite-scroll-disabled="disabled"
      v-infinite-scroll="loadHandler"
      :infinite-scroll-immediate="false"
    >
      <slot></slot>
    </div>
    <div v-if="loading" class="loading">
      <div class="loading-icon">........</div>
    </div>
    <div v-if="noMore" class="no-more">没有更多了~</div>
  </div>
</template>
<script setup lang="ts">
import { computed, ref, watch } from "vue";
const pullLoadRef = ref(null);
const params = defineModel("params", {
  type: Object,
  default: () => {
    return {};
  }
});
const value = defineModel("value", {
  type: Object,
  default: () => {
    return [];
  }
});
const props = defineProps({
  api: {
    type: Function,
    default: async () => {
      console.log("api");
    }
  },
  transformFormat: {
    type: Function,
    default: async () => {
      console.log("transformFormat");
    }
  },
  className: {
    type: String,
    default: ""
  },
  style: {
    type: String,
    default: ""
  }
});
const loading = ref(false);
const noMore = ref(false);
const disabled = computed(() => loading.value || noMore.value);

const loadHandler = async () => {
  try {
    loading.value = true;
    ++params.value.currentPage;
    const { data } = await props?.api(params.value);
    loading.value = false;
    noMore.value = Math.ceil(data.total / params.value.pageSize) <= data.current;
    await props.transformFormat(data.records);
    value.value = [...value.value, ...data.records];
  } catch (error) {
    console.log(error);
  }
};

const backTop = () => {
  pullLoadRef.value.scrollTo(0, 0);
};

watch(
  () => params.value.currentPage,
  val => {
    if (val == 1) {
      noMore.value = false;
      loading.value = false;
    }
  }
);
defineExpose({
  backTop
});
</script>
<style lang="scss">
.infinite-scroll {
  position: relative;
  height: 100%;
}
.no-more {
  width: 100%;
  height: 60px;
  font-size: 14px;
  line-height: 60px;
  color: #cccccc;
  text-align: center;
}
</style>
